// /////////////////////////////////////////////////////////////////////////////
//
// Name:            SoundManager.cpp
// Author:          Michael Bartsch (ZCCdark203)
//
// Desc :           The Sound Manager is the central interface point to all
//                  sound related functions of this program.
//
// License:         Copyright (C) 2009 Michael Bartsch and Contributors
//
//                  This program is free software: you can redistribute it
//                  and/or modify it under the terms of the zlib/libpng License.
//                  See main.cpp for conditions of distribution and use.
//
// /////////////////////////////////////////////////////////////////////////////

// Include files
#include "SoundManager.h"
#ifdef __COMPILE_WITH_SFML_AUDIO__
#include "../core/GameManager.h"


// SoundManager class
// SoundManager constructor.
SoundManager::SoundManager()
{
    init();
}

// SoundManager deconstructor.
SoundManager::~SoundManager()
{
    clear();
}

// Initialises the Sound Manager.
void SoundManager::init()
{
}

// Clears the Sound Manager.
void SoundManager::clear()
{
    removeSoundBuffers();
}

// Angelscript: Increases the reference counter.
void SoundManager::grab()
{
    // Dummy function.
}

// Angelscript: Decreases the reference counter.
void SoundManager::drop()
{
    // Dummy function.
}

// Gets the current global volume of all sounds.
f32 SoundManager::getGlobalVolume() const
{
    return sf::Listener::GetGlobalVolume();
}

// Gets the sound buffer with the given filename.
sf::SoundBuffer* SoundManager::getSoundBuffer(const std::string &fileName)
{
    std::map<std::string, sf::SoundBuffer*>::iterator it = mSoundBuffers.find(fileName);

    if(it != mSoundBuffers.end())
      return it->second;

    return NULL;
}

// Creates a sound buffer from the given file.
bool SoundManager::loadSoundBuffer(const std::string &fileName)
{
    // Get pointer to the File System of Irrlicht.
    IFileSystem *fileSystem = GameManager::Instance()->getDevice()->getFileSystem();

    // Has the sound buffer already been loaded?
    core::stringw wFilename = core::stringw(fileName.c_str());
    std::string fileBase = (fileSystem->getFileBasename(wFilename)).c_str();

    if(getSoundBuffer(fileBase) != NULL)
      return false;

    // Does the file exist?
    if(!fileSystem->existFile(fileName.c_str()))
      return false;

    // Open the given file and load the contents to the buffer.
    IReadFile *file = fileSystem->createAndOpenFile(fileName.c_str());

    if(!file)
      return false;

    long fSize = file->getSize();
    c8 *fBuffer = new c8[fSize+1];
    memset(fBuffer, 0, fSize+1);

    file->read(fBuffer, fSize);
    file->drop();

    // Create the sound buffer and add it to the map.
    sf::SoundBuffer *soundBuffer = new sf::SoundBuffer();
    soundBuffer->LoadFromMemory(fBuffer, fSize);

    mSoundBuffers[fileBase] = soundBuffer;

    // Clean up.
    delete[] fBuffer;

    return true;
}

// Creates a sound buffer from memory.
bool SoundManager::loadSoundBufferFromMemory(const std::string &name, c8 *buffer, long length)
{
    // Has a sound buffer with the same name already been loaded?
    if(getSoundBuffer(name) != NULL)
      return false;

    // Create the sound buffer and add it to the map.
    sf::SoundBuffer *soundBuffer = new sf::SoundBuffer();
    soundBuffer->LoadFromMemory(buffer, length);

    mSoundBuffers[name] = soundBuffer;

    // Clean up.
    return true;
}

// Removes all sound buffers.
void SoundManager::removeSoundBuffers()
{
    std::map<std::string, sf::SoundBuffer*>::iterator it;
    for(it = mSoundBuffers.begin(); it != mSoundBuffers.end(); it++)
      delete it->second;

    mSoundBuffers.clear();
}

// Removes the sound buffer with the given filename.
bool SoundManager::removeSoundBuffer(const std::string &fileName)
{
    // Try to remove the sound buffer.
    std::map<std::string, sf::SoundBuffer*>::iterator it = mSoundBuffers.find(fileName);

    if(it != mSoundBuffers.end())
    {
       sf::SoundBuffer *soundBuffer = it->second;

       delete soundBuffer;
       mSoundBuffers.erase(it);

       return true;
    }

    // We couldn't find the sound buffer and thus couldn't remove it.
    return false;
}

// Sets the global volume of all sounds.
void SoundManager::setGlobalVolume(f32 volume)
{
    sf::Listener::SetGlobalVolume(volume);
}

#endif // __COMPILE_WITH_SFML_AUDIO__

// End of File.
